﻿package bdz.common.effects{
	import flash.display.Sprite;
	import flash.display.BitmapData;
	import flash.filters.BlurFilter;
	import flash.utils.*;
	import flash.geom.*;
	import flash.events.Event;
	import flash.display.Bitmap;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.*;
	import flash.display.BlendMode;
	public class BitmapBlocks extends Sprite {
		private var _blockWidth:Number = 50;
		private var _blockHeight:Number = 50;
		private var references:Dictionary;
		private var counter:Number = 0;
		private var tweens:Dictionary;
		private var current:Number = 0;
		private var tweenDone:Number = 0;
		private var defY:Number;
		private var dpTme:Number;
		private var maxwidth:Number;
		private var blurrer:BlurFilter;
		function BitmapBlocks(todraw:BitmapData, defaultY:Number = 300) {
			tweens = new Dictionary();
			references = new Dictionary();
			defY = defaultY;
			createBlocks(todraw);
		}
		private function createBlocks(base:BitmapData):void {
			var mwidth:Number = Math.ceil(base.width/_blockWidth);
			maxwidth = mwidth;
			blurrer = new BlurFilter(0,0,1);
			for (var c:Number = 0; c<mwidth; c++) {
				var bmpCopy:BitmapData = new BitmapData(_blockWidth, base.height);
				bmpCopy.copyPixels(base, new Rectangle(c*_blockWidth, 0, _blockWidth, base.height), new Point(0,0));
				references[counter.toString()] = new Bitmap(bmpCopy.clone());
				references[counter.toString()].x = (c*_blockWidth);
				references[counter.toString()].filters = [blurrer];
				addChild(references[counter.toString()]);
				counter++;
				bmpCopy.dispose();

			}
			addEventListener(Event.ENTER_FRAME, transition);
			base.dispose();

		}
		public function recreate(base:BitmapData, defaultY:Number):void {

			for (var c:Number = 0; c<maxwidth; c++) {
				try {
					references[counter.toString()].bitmapData.dispose();
					removeChild(references[counter.toString()]);
				} catch (e:Error) {
				}
			}
			var mwidth:Number = Math.ceil(base.width/_blockWidth);
			maxwidth  = mwidth;
			defY = defaultY;
			counter = 0;
			current = 0;
			for (c = 0; c<mwidth; c++) {
				var bmpCopy:BitmapData = new BitmapData(_blockWidth, base.height);
				bmpCopy.copyPixels(base, new Rectangle(c*_blockWidth, 0, _blockWidth, base.height), new Point(0,0));
				references[counter.toString()] = new Bitmap(bmpCopy.clone());
				references[counter.toString()].scaleY = 0;
				references[counter.toString()].y = defY;
				references[counter.toString()].x = (c*_blockWidth);
				addChild(references[counter.toString()]);
				counter++;
				bmpCopy.dispose();
			}
			base.dispose();
		}
		private function transition(evt:Event) {
			if (current < counter) {
				tweens[current.toString()] = new Tween(references[current.toString()], "scaleY", Strong.easeOut, references[current.toString()].scaleY, 0, .8, true);
				new Tween(references[current.toString()], "y", Elastic.easeOut, references[current.toString()].y, defY, .6, true);
				tweens[current.toString()].addEventListener(TweenEvent.MOTION_CHANGE, reapplyFilter);
				tweens[current.toString()].addEventListener(TweenEvent.MOTION_FINISH, checkAll);
			}
			current++;
		}
		private function reapplyFilter(evt:TweenEvent):void{
			
			for each (var o:* in references){
				o.blendMode = BlendMode.HARDLIGHT;
			}
		}
		private function checkAll(evt:TweenEvent):void {
			if (tweenDone < counter-1) {
				tweens[tweenDone.toString()] = null;
				tweenDone++;
			} else {
				removeEventListener(Event.ENTER_FRAME, transition);
				current = 0;
				tweenDone = 0;
				clearTimeout(dpTme);
				dpTme = setTimeout(dispatchComplete, 500);
			}
		}
		private function checkRevertDone(evt:TweenEvent):void {
			if (tweenDone < counter-1) {
				tweens[tweenDone.toString()] = null;
				tweenDone++;
			} else {
				removeEventListener(Event.ENTER_FRAME, transitionBack);
				current = 0;
				tweenDone = 0;
				clearTimeout(dpTme);
				dpTme = setTimeout(dispatchClose, 500);
			}
		}
		private function dispatchClose() {
			clearTimeout(dpTme);
			dispatchEvent(new Event(Event.CLOSE));
		}
		private function dispatchComplete() {
			clearTimeout(dpTme);
			parent.removeChild(this);
			dispatchEvent(new Event(Event.COMPLETE));
		}
		public function revert():void {
			addEventListener(Event.ENTER_FRAME, transitionBack);
		}
		private function transitionBack(evt:Event) {
			if (current < counter) {
				new Tween(references[current.toString()], "scaleY", Strong.easeOut, 0, 1, .6, true);
				tweens[current.toString()] = new Tween(references[current.toString()], "y", Elastic.easeOut, references[current.toString()].y, 0, .8, true);
				tweens[current.toString()].addEventListener(TweenEvent.MOTION_FINISH, checkRevertDone);
			}
			current++;
		}
	}
}